#coding=utf-8
#LightCam 批量PING监控程序
#init by hfh 20150212

import multiprocessing,subprocess,threading
import socket,os,time,re,traceback,sys
import lc_libs,pymongo

def func(this):
	#agent_hostname=this['agent_hostname']
	ipaddr=this['ipaddr']
	hostname=this['hostname']
	count=this['count']
	ping_interval=this['ping_interval']
	timeout=this['timeout']
	severity=this['severity']
	interval=this['interval']
	schedule=this['schedule']
	holiday=this['holiday']
	
	Node=agent_hostname
	AlertGroup="MonitorPing"
	AlertKey=hostname+"_"+ipaddr

	try:
		#执行PING测试
		comd="ping -c "+count+" -i "+ping_interval+" -W "+timeout+" "+ipaddr+" |grep received"
		popen=subprocess.Popen(comd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
		#判断子进程是否结束
		while True:
			if popen.poll()==None:
				time.sleep(0.1)
				continue
			else:
				break
		#初始化标志文件
		#alertfilename="../alert/lc_mping_"+ipaddr
		#处理程序
		line=popen.stdout.read().strip("\n").strip("\r").split(',')
		if len(line)<4:
			print line
			line='unknow'
		else:
			for item in line:
				if "packet loss" in item:
					line=item.split()[0].strip('%').strip('')
			try:
				line=int(line)
			except:
				line='unknow'
		#数据入库
		#hdb.insert_historydb(Node,hostname+"_"+ipaddr,line)
		datas=[
			{"Node":Node,"Name":hostname+"_"+ipaddr,"Value":line,"Time":int(time.time())}
			]
		db.insertDatas(history_table,datas)
		
		#0:正常 绿色
		#1:不通 红色
		#2:有丢包 橙色
		#3:未知 灰色
		status=0
		
		
		
		if str(line)=='unknow':
			status=3
			Severity=severity
			Type="1"
			#Summary=hostname+"("+ipaddr+"),PING TIMEOUT."
			Summary=hostname+"("+ipaddr+")PING 异常."
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			#logfile.write(logdate+" "+strs+"\n")
			#logfile.flush()
		elif line==0:
			status=0
			Severity="1"
			Type="2"
			#Summary=hostname+"("+ipaddr+"),PING OK."
			Summary=hostname+"("+ipaddr+")PING 连通性正常."
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			#logfile.write(logdate+" "+strs+"\n")
			#logfile.flush()
		elif line==100:
			status=1
			Severity=severity
			Type="1"
			#Summary=hostname+"("+ipaddr+"),PING TIMEOUT."
			Summary=hostname+"("+ipaddr+")PING 不通."
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			#logfile.write(logdate+" "+strs+"\n")
			#logfile.flush()
		else:
			status=2
			Severity=severity
			Type="1"
			#Summary=hostname+"("+ipaddr+"),PING Packet Discard, "+str(line)+"% packet loss."
			Summary=hostname+"("+ipaddr+")PING 有丢包, 丢包率为"+str(line)+"% ."
			strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			print strs
			db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			#logfile.write(logdate+" "+strs+"\n")
			#logfile.flush()
		
		saveData(hostname,ipaddr,line,status)
		
	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" :\n"+excinfo+"\n")
		logfile.flush()
		time.sleep(1)

def saveData(hostname,ipaddr,loss,status):
	expr={'hostname':hostname,'ipaddr':ipaddr}
	datas={'hostname':hostname,'ipaddr':ipaddr,'loss':loss,'status':status,'Time':time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}
	sortcont=[("status",pymongo.ASCENDING)]
	opts=db.queryData(mping_table,expr,sortcont,0)
	res=db.genResult(opts)
	if len(res)==0:
		db.insertDatas(mping_table,datas)
	else:
		db.updateData(mping_table,expr,datas)
		

if __name__ == "__main__":

	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	
	#pool = multiprocessing.Pool(processes=1)
	#result = []
	
	#初始化events数据库
	#dbfile="../db/lc_events.db"
	#tablename="lc_events"
	#tablefield="Node varchar(32),AlertGroup varchar(64),AlertKey varchar(64),Severity varchar(8),Type varchar(8),LastOccurrence varchar(32),Summary varchar(256)"
	#db=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#db.create_db()
	#db.close_db()
	
	#初始化lc_history数据库
	#thismonth=time.strftime('%Y%m',time.localtime())
	#dbfile="../db/lc_history_"+thismonth+".db"
	#dbfile="../db/lc_history.db"
	#tablename="lc_mping"
	#tablefield="Node varchar(32),Name varchar(64),Value varchar(64),NTime varchar(32)"
	#hdb=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#hdb.create_db()
	#hdb.insert_historydb(Node,Name,Value)
	
	#清理标志文件
	#os.system("rm -f ../alert/lc_mping*")


	try:
		#初始化数据库
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		events_dbname='lc_events'
		events_tablename='lc_events'
		mping_tablename='mping'
		
		history_dbname='lc_history'
		history_tablename="lc_mping"
		
		events_db=db.useDatabase(events_dbname)
		events_table=db.UseCollection(events_db,events_tablename)
		mping_table=db.UseCollection(events_db,mping_tablename)
		
		history_db=db.useDatabase(history_dbname)
		history_table=db.UseCollection(history_db,history_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)

	#主程序
	MonitorList = []
	
	for lines in open(confname):
		if lines[0] == '#' or lines.split("\t")[0] not in (agent_hostname,'default'):
			continue

		line=lines.strip('\r\n').split('\t')
		dconf={}
		
		#dconf['agent_hostname']=line[0]
		dconf['ipaddr']=line[1]
		dconf['hostname']=line[2]
		dconf['count']=line[3]
		dconf['ping_interval']=line[4]
		dconf['timeout']=line[5]
		dconf['severity']=line[6]
		dconf['interval']=line[7]
		dconf['schedule']=line[8]
		dconf['holiday']=line[9]
	
		MonitorList.append(dconf)

	usedtime=0
	
	while True:
		time.sleep(1)
		realtime=int(time.time())
		
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		holiday_state = lc_libs.lc_isholiday()
		
		threads = []
		for i in MonitorList:
			if int(i['holiday']) == 1 and holiday_state == True:
				continue
				
			time_state = lc_libs.lc_schedule(i['schedule'])
			if time_state == False:
				continue
			
			flag=realtime%int(i['interval'])
			#print flag
			if flag<=usedtime:
				#print i
				t = threading.Thread(target=func,args=(i,))
				threads.append(t)
		
		for t in threads:
			t.start()
			while True:
				#print len(threading.enumerate())
				time.sleep(0.01)
				if(len(threading.enumerate()) < 100):
					break

		#排除执行程序导致的时间差
		usedtime=int(time.time())-realtime
		#print "usedtime:%s" % usedtime
